package com.metal.gear.certification.controller;



import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.metal.gear.certification.entity.dto.*;
import com.metal.gear.certification.entity.po.SysUser;
import com.metal.gear.certification.entity.po.SysUserDepart;
import com.metal.gear.certification.entity.po.SysUserRole;
import com.metal.gear.certification.entity.po.SysUserView;
import com.metal.gear.certification.mapper.SysUserViewMapper;
import com.metal.gear.certification.service.*;

import com.metal.gear.common.entity.Result;
import com.metal.gear.common.exception.SzlBusinessException;
import com.metal.gear.common.util.list.ListCompareResult;
import com.metal.gear.common.util.list.ListCompareUtil;
import com.metal.gear.common.util.query.SearchHelper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @Author scott
 * @since 2018-12-20
 */
@Slf4j
@RestController
@RequestMapping("/sys/user")
@Tag(name = "4.用户管理")
public class SysUserController {

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ISysDepartService sysDepartService;

    @Autowired
    private ISysUserRoleService sysUserRoleService;

    @Autowired
    private ISysUserDepartService sysUserDepartService;

    @Autowired
    private ISysDepartRoleUserService departRoleUserService;

    @Autowired
    private ISysDepartRoleService departRoleService;

    @Autowired
    private ISysUserViewService userViewService;

    @Autowired
    private SysUserViewMapper userViewMapper;

    

    @Operation(summary = "用户查询", description = "以列表的形式展示用户数据。用于页面上查询用户信息")
    @ApiOperationSupport(order = 1)
    //@PermissionData(pageComponent = "system/UserList")
    @RequestMapping(value = "/list", method = RequestMethod.GET,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<IPage<SysUserView>> queryPageList(UserSearchDto userSearchDto,
                                                    @RequestParam(defaultValue = "1") Integer pageNo,
                                                    @RequestParam(defaultValue = "10") Integer pageSize) throws Exception {
        QueryWrapper<SysUserView> wrapper = SearchHelper.generalQueryWrapper(userSearchDto);
        Page<SysUserView> page = Page.of(pageNo, pageSize);
        return Result.ok(userViewMapper.selectPage(page, wrapper));
    }

    @Operation(summary ="用户详情")
    @ApiOperationSupport(order = 1)
    @GetMapping(value = "/queryById",produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<SysUserView> queryById(@RequestParam String userId) {
        return Result.ok(userViewMapper.selectById(userId));
    }


    //@AutoLog(value = "新增用户")
    @Operation(summary ="新增用户")
    @ApiOperationSupport(order = 2)
    @RequestMapping(value = "/add", method = RequestMethod.POST,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> add(@RequestBody UserSaveDto saveDto) {
        SysUser sysUser = UserSaveDto.translateTo(saveDto);
        List<String> departIdList = saveDto.getDepartIdList();
        List<String> roleIdList = saveDto.getRoleIdList();
        sysUserService.saveUser(sysUser, roleIdList, departIdList);
        return Result.ok("添加成功！");
    }


    @Operation(summary = "校验用户账号是否唯一性", description = "true：唯一，false：不唯一")
    @ApiOperationSupport(order = 2)
    @RequestMapping(value = "/checkOnlyUser", method = RequestMethod.GET,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> checkOnlyUser(@RequestParam String username) {
        return Result.ok(Objects.isNull(sysUserService.getByName(username)));
    }

    //@AutoLog(value = "修改用户信息")
    @Operation(summary ="编辑用户")
    @ApiOperationSupport(order = 2)
    @PutMapping(value = "/edit",produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> edit(@RequestBody UserEditDto editDto) {
        SysUser sysUser = UserEditDto.translateTo(editDto);
        List<String> roleIdList = CollUtil.emptyIfNull(editDto.getRoleIdList());
        List<String> departIdList = CollUtil.emptyIfNull(editDto.getDepartIdList());
        sysUserService.editUser(sysUser, roleIdList, departIdList);
        return Result.ok("修改成功!");
    }

    //@AutoLog(value = "删除用户")
    @Operation(summary ="删除用户")
    @ApiOperationSupport(order = 2)
    @DeleteMapping(value = "/delete",produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> delete(@RequestParam String userId) {
        sysUserService.deleteUser(userId);
        return Result.ok("删除用户成功");
    }

    //@AutoLog(value = "批量删除用户")
    @Operation(summary ="批量删除用户")
    @ApiOperationSupport(order = 2)
    @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> deleteBatch(@RequestParam(name = "ids") String ids) {
        this.sysUserService.deleteBatchUsers(ids);
        return Result.ok("批量删除用户成功");
    }


    //@AutoLog(value = "冻结&解冻用户")
    @Operation(summary ="冻结&解冻用户")
    @ApiOperationSupport(order = 2)
    @RequestMapping(value = "/frozenBatch", method = RequestMethod.PUT,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> frozenBatch(@RequestParam String userId,
                                       @RequestParam String status) {
        sysUserService.changeStatus(userId, status);
        return Result.ok("操作成功！");
    }

    //@AutoLog(value = "重置密码")
    @Operation(summary = "重置密码", description = "管理员直接修改某一的密码用户")
    @ApiOperationSupport(order = 2)
    @PutMapping(value = "/resetPassword",produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> resetPassword(@RequestBody UserResetPasswordDto changePasswordDto) {
        String userId = changePasswordDto.getId();
        String password = changePasswordDto.getPassword();
        SysUser sysUser = sysUserService.getById(userId);
        sysUser.setPassword(password);
        sysUserService.changePassword(sysUser);
        return Result.ok();
    }

    //@AutoLog(value = "修改密码")
    @Operation(summary = "修改密码", description = "用户修改自身密码")
    @ApiOperationSupport(order = 2)
    @PutMapping(value = "/updatePassword",produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> updatePassword(@RequestBody UserChangePasswordDto changPasswordDto) {
//        String username = changPasswordDto.getUsername();
//        String oldPassword = changPasswordDto.getOldPassword();
//        String newPassword = changPasswordDto.getNewPassword();
//        String confirmPassword = changPasswordDto.getConfirmPassword();
//        LoginUser currentUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//        if (!currentUser.getUsername().equals(username)) {
//            return Result.error("只允许修改自己的密码！");
//        }
//        SysUser user = this.sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
//        if (user == null) {
//            return Result.error("用户不存在！");
//        }
//        sysUserService.changePassword(username, oldPassword, newPassword, confirmPassword);
        return Result.ok();
    }

    @Operation(summary ="用户角色id列表")
    @ApiOperationSupport(order = 3)
    @RequestMapping(value = "/queryUserRole", method = RequestMethod.GET,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<List<String>> queryUserRole(@RequestParam(name = "userId") String userId) {
        return Result.ok(sysUserRoleService.listRoleIdByUserId(userId));
    }


    @Operation(summary ="导出ExcelProperty")
    @ApiOperationSupport(order = 4)
    @RequestMapping(value = "/exportXls", method = RequestMethod.GET,produces = {MediaType.APPLICATION_JSON_VALUE})
    public ModelAndView exportXls(SysUser sysUser, HttpServletRequest request) {
        throw new SzlBusinessException("接口未实现");
    }

    @Operation(summary ="通过ExcelProperty导入数据")
    @ApiOperationSupport(order = 4)
    @RequestMapping(value = "/importExcelProperty", method = RequestMethod.POST,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<?> importExcelProperty(HttpServletRequest request, HttpServletResponse response) throws IOException {
        throw new SzlBusinessException("接口未实现");
    }


    @Operation(summary ="批量查询")
    @ApiOperationSupport(order = 4)
    @RequestMapping(value = "/queryByIds", method = RequestMethod.GET,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<List<SysUser>> queryByIds(@RequestParam String userIds) {
        String[] userId = userIds.split(",");
        Collection<String> idList = Arrays.asList(userId);
        return Result.ok(sysUserService.listByIds(idList));
    }


    @Operation(summary ="查询某一角色下的用户")
    @ApiOperationSupport(order = 4)
    @RequestMapping(value = "/userRoleList", method = RequestMethod.GET,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<IPage<SysUserView>> userRoleList(@RequestParam(defaultValue = "1") Integer pageNo,
                                                   @RequestParam(defaultValue = "10") Integer pageSize,
                                                   @RequestParam String roleId) {
        LambdaQueryWrapper<SysUserView> wrapper = Wrappers.lambdaQuery();
        wrapper.like(SysUserView::getRoleIds, roleId);

        Page<SysUserView> page = Page.of(pageNo, pageSize);

        return Result.ok(userViewMapper.selectPage(page, wrapper));

    }

    //@AutoLog(value = "给指定角色添加用户")
    @ApiOperationSupport(order = 5)
    @Operation(summary ="给指定角色添加用户，该接口中userId不存在于数据库中时将移除该userId")
    @RequestMapping(value = "/addSysUserRole", method = RequestMethod.POST,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> addSysUserRole(@RequestBody SysUserRoleDto sysUserRoleDto) {
        String roleId = sysUserRoleDto.getRoleId();
        List<String> userIdInRequest = sysUserRoleDto.getUserIdList();
        List<String> userIdInDb = sysUserRoleService.listUserIdByRoleId(roleId);

        ListCompareResult<String> compareResult = ListCompareUtil.doCompareString(userIdInRequest, userIdInDb);
        List<String> newList = compareResult.getNewList();
        List<String> lostList = compareResult.getLostList();

        newList.forEach((userId) -> sysUserRoleService.save(new SysUserRole(userId, roleId)));
        lostList.forEach((userId) -> sysUserRoleService.deleteByUserIdAndRoleId(userId, roleId));

        return Result.ok();
    }

    //@AutoLog(value = "给指定角色添加用户")
    @ApiOperationSupport(order = 5)
    @Operation(summary ="给指定角色添加用户，该接口只做新增")
    @RequestMapping(value = "/addSysUserRoleOnlyAdd", method = RequestMethod.POST,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> addSysUserRoleOnlyAdd(@RequestBody SysUserRoleDto sysUserRoleDto) {
        String roleId = sysUserRoleDto.getRoleId();

        List<String> userIdInRequest = sysUserRoleDto.getUserIdList();
        List<String> userIdInDb = sysUserRoleService.listUserIdByRoleId(roleId);

        ListCompareUtil.doCompareString(userIdInRequest, userIdInDb)
                .getNewList()
                .forEach((userId) ->
                        sysUserRoleService.save(new SysUserRole(userId, roleId)));
        return Result.ok();
    }

    //@AutoLog(value = "删除指定角色的用户关系")
    @ApiOperationSupport(order = 5)
    @Operation(summary ="删除指定角色的用户关系")
    @RequestMapping(value = "/deleteUserRole", method = RequestMethod.DELETE,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> deleteUserRole(@RequestParam String roleId,
                                          @RequestParam String userId) {
        sysUserRoleService.deleteByUserIdAndRoleId(userId, roleId);
        return Result.ok();
    }

    //@AutoLog(value = "批量删除指定角色的用户关系")
    @ApiOperationSupport(order = 5)
    @Operation(summary ="批量删除指定角色的用户关系")
    @RequestMapping(value = "/deleteUserRoleBatch", method = RequestMethod.DELETE,produces = {MediaType.APPLICATION_JSON_VALUE})
    @Transactional
    public Result<SysUserRole> deleteUserRoleBatch(@RequestParam String roleId,
                                                   @RequestParam String userIds) {
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<SysUserRole>();
        queryWrapper.eq("role_id", roleId);
        queryWrapper.in("user_id", Arrays.asList(userIds.split(",")));
        sysUserRoleService.remove(queryWrapper);
        return Result.ok("删除成功!");
    }

    @Operation(summary ="组织机构用户列表")
    @ApiOperationSupport(order = 6)
    @RequestMapping(value = "/departUserList", method = RequestMethod.GET,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<IPage<SysUserView>> departUserList(@RequestParam(defaultValue = "1") Integer pageNo,
                                                     @RequestParam(defaultValue = "10") Integer pageSize,
                                                     @RequestParam String departId,
                                                     @RequestParam String realName) {
        Page<SysUserView> page = Page.of(pageNo, pageSize);
        LambdaQueryWrapper<SysUserView> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(StrUtil.isNotEmpty(departId), SysUserView::getDepartIds, departId);
        wrapper.like(StrUtil.isNotEmpty(realName), SysUserView::getRealname, realName);
        wrapper.orderByDesc(SysUserView::getCreateTime);

        return Result.ok(userViewMapper.selectPage(page, wrapper));

    }

    //@AutoLog(value = "给指定组织机构添加对应的用户")
    @ApiOperationSupport(order = 6)
    @Operation(summary ="给指定组织机构添加对应的用户，该接口中userID不存在于数据库中时将删除该user")
    @Transactional
    @RequestMapping(value = "/editSysDepartUser", method = RequestMethod.POST,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> editSysDepartUser(@RequestBody SysDepartUsersDto sysDepartUsersDto) {
        String departId = sysDepartUsersDto.getDepId();
        List<String> userIdList = sysDepartUsersDto.getUserIdList();
        List<String> userIdInDb = sysUserDepartService.listDepartIdByUserId(departId);
        ListCompareResult<String> compareResult = ListCompareUtil.doCompareString(userIdList, userIdInDb);

        compareResult.getNewList()
                .forEach((userId) -> sysUserDepartService.save(new SysUserDepart(userId, departId)));
        compareResult.getLostList()
                .forEach((userId) -> sysUserDepartService.deleteByUserIdAndDepartId(userId, departId));
        return Result.ok();
    }

    //@AutoLog(value = "给指定组织机构添加对应的用户")
    @ApiOperationSupport(order = 6)
    @Operation(summary ="给指定组织机构添加对应的用户，该接口只会增加用户")
    @Transactional
    @RequestMapping(value = "/editSysDepartUserOnlyAdd", method = RequestMethod.POST,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> editSysDeparUserOnlyAdd(@RequestBody SysDepartUsersDto sysDepartUsersDto) {
        String departId = sysDepartUsersDto.getDepId();
        List<String> userIdList = sysDepartUsersDto.getUserIdList();
        List<String> userIdInDb = sysUserDepartService.listDepartIdByUserId(departId);
        ListCompareResult<String> compareResult = ListCompareUtil.doCompareString(userIdList, userIdInDb);

        compareResult.getNewList()
                .forEach((userId) -> sysUserDepartService.save(new SysUserDepart(userId, departId)));
        return Result.ok();
    }

    //@AutoLog(value = "删除指定组织机构的用户关系")
    @ApiOperationSupport(order = 6)
    @Operation(summary ="删除指定组织机构的用户关系")
    @RequestMapping(value = "/deleteUserInDepart", method = RequestMethod.DELETE,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> deleteUserInDepart(@RequestParam(name = "departId") String departId,
                                              @RequestParam(name = "userId") String userId) {
        sysUserDepartService.deleteByUserIdAndDepartId(userId, departId);
        return Result.ok();
    }

    //@AutoLog(value = "批量删除指定机构的用户关系")
    @ApiOperationSupport(order = 6)
    @Operation(summary ="批量删除指定机构的用户关系")
    @RequestMapping(value = "/deleteUserInDepartBatch", method = RequestMethod.DELETE,produces = {MediaType.APPLICATION_JSON_VALUE})
    public Result<Boolean> deleteUserInDepartBatch(@RequestParam(name = "depId") String depId,
                                                   @RequestParam(name = "userIds") String userIds) {

        LambdaQueryWrapper<SysUserDepart> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SysUserDepart::getDepId, depId);
        wrapper.in(SysUserDepart::getUserId, Arrays.asList(userIds.split(",")));
        sysUserDepartService.remove(wrapper);
        return Result.ok("删除成功!");
    }

}
